//
//  MainViewController.swift
//  WeiBo
//
//  Created by Tony on 2017/12/20.
//  Copyright © 2017年 Tony. All rights reserved.
//

import UIKit

class MainViewController: UITabBarController {

    //lazy var composeBtn: UIButton = UIButton.createBtn(imageName: "tabbar_compose_icon_add", bgImageName: "tabbar_compose_button")
    
    lazy var composeBtn: UIButton = UIButton.init(imageName: "tabbar_compose_icon_add", bgImageName: "tabbar_compose_button")
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        /*
         设置颜色，假如每个控制器都是这样颜色，那应该设置全局的颜色
         tabBar.tintColor = UIColor.orange
         设置全局应该在AppDelagate内设置
        */
        // 初始化
        // setup()
        // 使用storyBoard初始化
        
        setupComposeBtn()
        
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        // 在这里调整tabbar纽，不要在viewDidLoad()方法中调整
        // 因为viewDidLoad()方法中调整tabbar属性，会被覆盖
        
        guard let item = tabBar.items?[2] else {
            return;
        }
        // 将中间按纽置为不可用
        // 如下代码也可以通过storyborard设置
        item.isEnabled = false
        
    }
}


extension MainViewController {
    
    func setupComposeBtn() {
        // 通过懒加载增加发布按纽
        tabBar.addSubview(composeBtn)
        composeBtn.center = CGPoint.init(x: tabBar.center.x, y: tabBar.bounds.size.height * 0.5)
        
        // 事件监听，两种写法，最为常用第一种写法
        composeBtn.addTarget(self, action: #selector(MainViewController.composeBtnClick), for: .touchUpInside)
        //composeBtn.addTarget(self, action: Selector("composeBtnClick"), for: .touchUpInside)
        //composeBtn.addTarget(self, action: "composeBtnClick", for: .touchUpInside)

        
    }
    
    // 事件监听本质:发送消息，方法包装成@SEL，存放在类的方法列中，根据@SEL查找impl指针(函数指针)
    // SWift事件监听两种方法:action: "test"与action: Selector("test")
    // SWift使用private修饰的方法，不会添加到类的方法列表中
    // SWift使用@objc、private修饰的方法，会添加到类的方法列表中同时保证不会其他类调用
    @objc private func composeBtnClick() {
        mySelfLog("composeBtnClick")
    }
}

// MARK: ---
// 类扩展前加上private，表明类扩展内函数只能当前类调用
private extension MainViewController {
    func setup() {
        
        // 方法1：纯代码
        #if true
            addChildViewController(HomeViewController(), title: "首页", imageName: "tabbar_home")
            addChildViewController(MessageViewController(), title: "消息", imageName: "tabbar_message_center")
            addChildViewController(DiscoverViewController(), title: "发现", imageName: "tabbar_discover")
            addChildViewController(ProfileViewController(), title: "我", imageName: "tabbar_profile")
        #endif
        
        // 方法2：通过字符串创建类或对象（有知识点不懂）
        #if false
            addChildViewController(childVcName: "HomeViewController", title: "首页", imageName: "tabbar_home")
            addChildViewController(childVcName: "MessageViewController", title: "消息", imageName: "tabbar_message_center")
            addChildViewController(childVcName: "DiscoverViewController", title: "发现", imageName: "tabbar_discover")
            addChildViewController(childVcName: "ProfileViewController", title: "我", imageName: "tabbar_profile")
        #endif
        
        // 方法3：通过加载json文件创建
        
        #if false
            // 1、获取对应的json路径
            guard let jsonPath = Bundle.main.path(forResource: "MainVCSettings", ofType: "json") else {
                mySelfLog("未能获取json对应路径")
                return;
            }
            
            // 2、获取json文件内容
            let jsonUrl = URL.init(fileURLWithPath: jsonPath)
            let jsonData = try! Data.init(contentsOf: jsonUrl)
            
            // 补充知识点
            /*
             若调用系统方法，方法后有一个关键字throws，证明该方法会抛出异常，Swift人如下三种异常的处理方式
             1、catch方式（标准方式）：程序员手动处理异常
             do {
             let tempObj = try JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers)
             } catch {
             // 若上述方法有异常，catch代码块会捕获到异常，并且会一个临时系统变量error
             mySelfLog(error)
             }
             2、try？方式（常用方式）：系统自动处理，直接告诉系统若这段代码有异常则返回nil，没有异常返回对应返回值
             let tempObj = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers)
             3、try!方式(不常用方式)：直接告诉系统，这段代码没有异常。这种处理较危险，若真产生异常，程序直接崩溃
             let tempObj = try! JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers)
             */
            let tempObj = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers)
            
            guard let dictArray = tempObj as? [[String:  AnyObject]] else {
                return;
            }
            
            for dict in dictArray {
                guard let vcName = dict["vcName"] as? String else {
                    // 循环内不应该写return，也不应该写break
                    continue
                }
                guard let title = dict["title"] as? String else {
                    continue
                }
                guard let imageName = dict["imageName"] as? String else {
                    continue
                }
                
                mySelfLog("vcName=\(vcName),title=\(title),imageName=\(imageName)")
            }
            
            
        #endif
        
        
    }
    // MARK:第2种初始化方法
    func addChildViewController(childVcName:  String, title:  String, imageName:  String) {
        
        // 根据字符串创建类对象，能创建成功前提：工程内有对应的类
        // 与OC不同，Swift引入命名空间概念，不能再根据类名创建类，除了类名还要加上命名空间才能创建类对象
        
        /*
         // 1、获取命名空间
         guard let nameSpace = Bundle.main.infoDictionary!["CFBundleExecutable"] as? String else {
         mySelfLog(message: "未能获取命名空间")
         return
         }
         
         // 2、创建对应类
         guard let childVcClass = NSClassFromString(nameSpace + "." + childVcName) else {
         mySelfLog(message: "未能获取到对应类")
         return;
         }
         
         // 3、将anyClass类型转为控制器类型
         guard let childVcType = childVcClass as? UIViewController.Type else {
         mySelfLog(message: "未能获取到对应控制器类型")
         return
         }
         
         // 4、创建对应类对象
         let childController = childVcType.init(coder: )
         
         // 设置属性
         childController.title = title
         childController.tabBarItem.image = UIImage(named: imageName)
         childController.tabBarItem.selectedImage = UIImage(named: imageName+"_highlighted")
         
         // 包装导航控制器
         let childNav = UINavigationController.init(rootViewController: childController)
         
         // 成为TabBar控制器的子控制器
         addChildViewController(childNav)
         */
    }
    
    
    // MARK:第1种初始化方法
    /*
     private私有方法，只有在同一文件中访问
     此方法名与系统方法同名
     但Swift支持方法重载，但OC不支持
     方法名一样，只在参数类型或参数个数不同，就支持方法重载
     */
    func addChildViewController(_ childController:  UIViewController, title:  String, imageName:  String) {
        
        // 设置属性
        childController.title = title
        childController.tabBarItem.image = UIImage(named: imageName)
        childController.tabBarItem.selectedImage = UIImage(named: imageName+"_highlighted")
        
        // 包装导航控制器
        let childNav = UINavigationController.init(rootViewController: childController)
        
        // 成为TabBar控制器的子控制器
        addChildViewController(childNav)
        
    }
}
